package org.yu.team2023.flashdays.registries;

import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.items.IItemHandlerModifiable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.annotation.Nonnull;

public interface SimpleEntityBlock<T extends BlockEntity> extends EntityBlock {
    @Nullable
    @Override
    default <T extends BlockEntity> BlockEntityTicker<T> getTicker(@NotNull Level level, @NotNull BlockState state, @NotNull BlockEntityType<T> blockEntityType) {
        return blockEntityType.equals(getBlockEntityType()) ? (world, pos, state1, t) -> {
            if (t instanceof SimpleTicker simpleTicker) {
                simpleTicker.commonTick(world, pos, state1);
            }
        } : null;
    }

    @Nullable BlockEntityType<T> getBlockEntityType();

    @Nullable
    @Override
    default T newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState state) {
        var ent=getBlockEntityType();
        return ent==null?null:ent.create(pos, state);
    }

    default void spawnDrops(@Nonnull Level level, @Nonnull BlockPos pos, IItemHandlerModifiable handlerModifiable) {
        for (int i = 0; i < handlerModifiable.getSlots(); i++) {
            ItemStack stack = handlerModifiable.getStackInSlot(i);
            ItemEntity entity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 0.1, pos.getZ() + 0.5, stack.copy());
            level.addFreshEntity(entity);
            handlerModifiable.setStackInSlot(i, ItemStack.EMPTY);
        }
    }

    ;

    default void onRemove(@Nonnull BlockState state, @Nonnull Level level, @Nonnull BlockPos pos, @Nonnull BlockState newState) {
        if (!level.isClientSide && (!state.is(newState.getBlock()) || !newState.hasBlockEntity())) {
            BlockEntity be = level.getBlockEntity(pos);
            if (be != null) {
                be.getCapability(ForgeCapabilities.ITEM_HANDLER, null).ifPresent(handler -> {
                    if (handler instanceof IItemHandlerModifiable modifiable) {
                        spawnDrops(level, pos, modifiable);
                    }
                });
            }
        }
    }
    @SuppressWarnings({"all"})
    default  T getBlockEntity(BlockGetter level, BlockPos pos){
        return (T)level.getBlockEntity(pos);
    }

    interface SimpleTicker {
        void clientTick(@NotNull Level world, @NotNull BlockPos pos, @NotNull BlockState state);

        void serverTick(@NotNull Level world, @NotNull BlockPos pos, @NotNull BlockState state);

        default void commonTick(@NotNull Level world, @NotNull BlockPos pos, @NotNull BlockState state) {
            if (!world.isClientSide) {
                serverTick(world, pos, state);
            } else {
                clientTick(world, pos, state);
            }
        }
    }
}
